package com.sg.java;

import cn.hutool.core.util.ObjectUtil;
import com.sg.java.apps.ReadHdfsFile;
import com.sg.java.entity.CMS_VOLT_CURVE;
import com.sg.java.entity.Gx;
import com.sg.java.entity.TimeShare;
import com.sg.java.entity.VoltU1_96;
import com.sg.java.util.CsvUtils;
import com.sg.java.util.EntityUtils;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.lang3.StringUtils;

import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName TimeSharing
 * @Author wangshuo
 * @Date 2023/7/6 09:22
 * @Version 1.0
 **/
public class TimeSharing {
    // 定义有序的阈值数组，用于确定条件范围
    private static final double[] thresholds = {180, 190, 198, 200, 205, 210, 220, 230, 235, 240, 245, 250, 253, 258};

    private static final String[] headers = new String[]{"user_id", "volt_code", "meter_id", "org_no", "org_name", "user_name"};

    private static final String path = ReadHdfsFile.pbFilePath;

    private static boolean flag = true;

    private static ConcurrentHashMap<String, String> yhMap = new ConcurrentHashMap<>();

    private static HashMap<String, String> gx = new HashMap<>();

//    private static HashMap<String, List<CMS_VOLT_CURVE>> pbMap = new HashMap<>();

    public static void getResult(CMS_VOLT_CURVE curve, String ds, HashMap<String, List<TimeShare>> pbMap) throws Exception {

        if (flag) {
            String yhgx = ds +"yhgx111";
            try {
                yhMap = CsvUtils.CsvToObject(path, headers, "202304", yhgx, null);
                gx = CsvToZxbGx(path, headers, ds + "pbxlbdz111");
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            flag = false;
        }

        String s = yhMap.get(curve.getMETER_ID());
        if (StringUtils.isNoneBlank(s)) {
            Gx gx = EntityUtils.StringToYhGx(s);
            if (pbMap.get(gx.getPid()) == null) {
                List<TimeShare> shares = inTimeSharing(curve, gx.getPid(), ds);
                pbMap.put(gx.getPid(), shares);
            } else {
                List<TimeShare> shares = pbMap.get(gx.getPid());
                List<TimeShare> timeShareList = judgeCmsVoltCurve(curve, shares);
                pbMap.put(gx.getPid(), timeShareList);
            }
        }


    }

    /**
     * 非第一次进入
     * 判断累加方法
     *
     * @param cmsVoltCurve  当前传入需要判断的电压原始数据对象
     * @param timeShareList 此前15个状态对象
     */
    public static List<TimeShare> judgeCmsVoltCurve(CMS_VOLT_CURVE cmsVoltCurve, List<TimeShare> timeShareList) {
        for (VoltU1_96 voltU196 : cmsVoltCurve.getCOL_TIME$U()) {
            if (!StringUtils.isEmpty(voltU196.getV())) {
                double v1 = Double.parseDouble(voltU196.getV());

                //获取对应字段名 u1...
                String clazzFieldName = "u" + voltU196.getU();

                int stateArea = 15; // 定义范围状态15个
                int start = 0; // 二分查找的起始位置，最小索引
                int end = thresholds.length - 1; // 二分查找的结束位置，最大索引

                while (start <= end) { // 在查找范围内循环进行二分查找
                    int center = (start + end) / 2; // 计算中间索引
                    if (v1 < thresholds[center]) { // 如果目标值小于中间阈值
                        stateArea = center + 1; // 更新满足条件的范围状态+1
                        end = center - 1; // 缩小查找范围到左侧
                    } else {
                        start = center + 1; // 缩小查找范围到右侧
                    }
                }
                // 根据满足条件的范围的索引，获取对应的timeShareList元素，并调用getCount方法进行处理
                getCount(clazzFieldName, timeShareList.get(stateArea - 1));
            }
        }
        return timeShareList;
    }


    /**
     * 第一次进入
     *
     * @param cmsVoltCurve 配变下需要判断的电压原始数据对象
     * @param pbId         配变id
     * @return 返回处理数据
     */
    public static List<TimeShare> inTimeSharing(CMS_VOLT_CURVE cmsVoltCurve, String pbId, String ds) throws Exception {
//        HashMap<String, String> gx = CsvToZxbGx(path, headers, ds + "pbxlbdz111");
        //0公司名称 1变电站名称 2变电站id 3线路名称 4线路id 5配变名称 6配变id
//        String[] split = gx.get(pbId).split("!@@");
        String s = gx.get(pbId);
        //初始化当前pb的15个状态
        List<TimeShare> timeShareList = new ArrayList<>();
        for (int i = 1; i <= 15; i++) {
            TimeShare timeShare = new TimeShare();
            timeShare.setStateArea(i);
            timeShare.setStatisticTime(cmsVoltCurve.getDATA_DATE());
            timeShare.setPbId(pbId);
            if (StringUtils.isNotBlank(s)) {
                String[] split = s.split("!@@");
                timeShare.setPbName(split[5]);
                timeShare.setBdzId(split[2]);
                timeShare.setBdzName(split[1]);
                timeShare.setXlId(split[4]);
                timeShare.setXlName(split[3]);
                timeShare.setMxId(split[6]);
            }

            // 生成一个随机的UUID
            UUID randomUUID = UUID.randomUUID();
            timeShare.setId(randomUUID.toString());
            timeShareList.add(timeShare);
        }
        return judgeCmsVoltCurve(cmsVoltCurve, timeShareList);
    }


    //1.先构建一个配变的树结构（map）k是配变id v是一个list<CMS_VOLT_CURVE>
    public void pbTree() throws Exception {

        String pbgx = "pbgx111";
        String yhgx = "yhgx111";
        String yhdy = "202304yhdycount";

        String[] headers = new String[]{"user_id", "volt_code", "meter_id", "org_no", "org_name", "user_name"};
        String month = pbgx.substring(4, 6);
        String path = ReadHdfsFile.pbFilePath;

        yhMap = CsvUtils.CsvToObject(path, headers, month, yhgx, null);
    }

    /**
     * 处理统计方法
     *
     * @param clazzFieldName 对象属性名
     * @param timeShare      15个状态对应的对象
     */
    //public void getCount(String clazzFieldName, TimeShare timeShare, int stateArea) {
    public static void getCount(String clazzFieldName, TimeShare timeShare) {
        try {
            // 获取 timeShare1 的对应字段的 getter 和 setter 方法
            PropertyDescriptor timeSharePD = new PropertyDescriptor(clazzFieldName, TimeShare.class);
            Method timeShareGetter = timeSharePD.getReadMethod();
            Method timeShareSetter = timeSharePD.getWriteMethod();

            // 调用 timeShare 的 getter 方法，获取当前点数对应状态的统计数值
            int result = (int) timeShareGetter.invoke(timeShare);
            //System.out.println("Getter Result: " + result);

            // 调用 timeShare 的 setter 方法，累加数值
            timeShareSetter.invoke(timeShare, result + 1);
            //System.out.println("Setter Result: " + timeShareGetter.invoke(timeShare));

            //调用setStateArea方法，并塞入区间状态stateArea
            //PropertyDescriptor stateAreaPD = new PropertyDescriptor("stateArea", TimeShare.class);
            //Method writeMethod = stateAreaPD.getWriteMethod();
            //writeMethod.invoke(timeShare, stateArea);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static String findFile(String filePath, String zpbyhName) throws Exception {
        File file = new File(filePath);
        String[] names = file.list();
        for (String name : names) {
            boolean a = name.startsWith(zpbyhName);
            if (a) {
                return filePath + name;
            }
        }
        throw new Exception("文件名有误");
    }

    public static HashMap<String, String> CsvToZxbGx(String filePath, String[] headers, String fileName) throws Exception {
        String file = findFile(filePath, fileName);
        HashMap<String, String> hashMap = new HashMap<>();
        //创建CSVFormat
        CSVFormat formator = CSVFormat.DEFAULT.withHeader(headers);
        FileReader fileReader = null;
        CSVParser parser = null;
        try {
            fileReader = new FileReader(file);
            parser = new CSVParser(fileReader, formator);
            for (CSVRecord next : parser) {
                if (ObjectUtil.isNull(next) || next.size() < 2) {
                    continue;
                }
                //0公司名称 1变电站名称 2变电站id 3线路名称 4线路id 5配变名称 6配变id
                String s = next.get(0) + "!@@" + next.get(1) + "!@@" + next.get(2) + "!@@" + next.get(3) + "!@@" + next.get(4) + "!@@" + next.get(5)+ "!@@" + next.get(7);
                hashMap.put(next.get(6), s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                parser.close();
                fileReader.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return hashMap;
    }

}
